home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Applications / Macintosh Tracker 1.20 / source / Tracker Client Folder / Core 18⁄March⁄1994 / CSack.c < prev    next >
Encoding:
Text File  |  1993-05-15  |  15.8 KB  |  262 lines  |  [TEXT/KAHL]

  1.  Block");
  2.                 (**Temp).Next = (**FirstBlock).Next;
  3.                 (**Temp).NumElements = (**FirstBlock).NumElements + 1;
  4.                 (**Temp).NumBytes = (**FirstBlock).NumBytes + BytesPerElement;
  5.                 ERROR((**Temp).NumBytes % BytesPerElement != 0,PRERR(ForceAbort,
  6.                     "CSack::PushElement element array size inconsistency"));
  7.                 HRNGCHK(Temp,&((**Temp).Data[BytesPerElement]),(**FirstBlock).NumBytes);
  8.                 HRNGCHK(FirstBlock,&((**FirstBlock).Data[0]),(**FirstBlock).NumBytes);
  9.                 MemCpy(&((**Temp).Data[BytesPerElement]),&((**FirstBlock).Data[0]),
  10.                     (**FirstBlock).NumBytes);
  11.                 HRNGCHK(Temp,&((**Temp).Data[0]),BytesPerElement);
  12.                 MemCpy(&((**Temp).Data[0]),Element,BytesPerElement);
  13.                 ReleaseHandle((Handle)FirstBlock);
  14.                 FirstBlock = Temp;
  15.             }
  16.          else
  17.             {
  18.                 Temp = (SackBlock**)AllocHandle(sizeof(SackBlock) + BytesPerElement);
  19.                 SetTag(Temp,"CSack Block");
  20.                 (**Temp).Next = FirstBlock;
  21.                 (**Temp).NumElements = 1;
  22.                 (**Temp).NumBytes = BytesPerElement;
  23.                 HRNGCHK(Temp,&((**Temp).Data[0]),BytesPerElement);
  24.                 MemCpy(&((**Temp).Data[0]),Element,BytesPerElement);
  25.                 FirstBlock = Temp;
  26.             }
  27.     }
  28.  
  29.  
  30. MyBoolean        CSack::KillElement(void* Element)
  31.     {
  32.         SackBlock**            Scan;
  33.         SackBlock**            Lag;
  34.         register short    Index;
  35.  
  36.         ERROR(Initialized != True,PRERR(ForceAbort,
  37.             "CSack::KillElement called on uninitialized object."));
  38.         EXECUTE(Scannable = False;)
  39.         Scan = FirstBlock;
  40.         Lag = NIL;
  41.         while (Scan != NIL)
  42.             {
  43.                 CheckHandleExistence((Handle)Scan);
  44.                 for (Index = 0; Index < (**Scan).NumBytes; Index += BytesPerElement)
  45.                     {
  46.                         HRNGCHK(Scan,&((**Scan).Data[Index]),BytesPerElement);
  47.                         if (MemEqu(Element,&((**Scan).Data[Index]),BytesPerElement))
  48.                             {
  49.                                 SackBlock**            Temp;
  50.                                 register short    Count;
  51.  
  52.                                 Temp = (SackBlock**)AllocHandle((**Scan).NumBytes
  53.                                     - BytesPerElement + sizeof(SackBlock));
  54.                                 SetTag(Temp,"CSack Block");
  55.                                 (**Temp).Next = (**Scan).Next;
  56.                                 (**Temp).NumElements = (**Scan).NumElements - 1;
  57.                                 (**Temp).NumBytes = (**Scan).NumBytes - BytesPerElement;
  58.                                 HRNGCHK(Temp,&((**Temp).Data[0]),Index);
  59.                                 HRNGCHK(Scan,&((**Scan).Data[0]),Index);
  60.                                 MemCpy(&((**Temp).Data[0]),&((**Scan).Data[0]),Index);
  61.                                 HRNGCHK(Temp,&((**Temp).Data[Index]),(**Scan).NumBytes
  62.                                     - BytesPerElement - Index);
  63.                                 HRNGCHK(Scan,&((**Scan).Data[Index + BytesPerElement]),
  64.                                     (**Scan).NumBytes - BytesPerElement - Index);
  65.                                 MemCpy(&((**Temp).Data[Index]),&((**Scan).Data[Index + BytesPerElement]),
  66.                                     (**Scan).NumBytes - BytesPerElement - Index);
  67.                                 if (Lag == NIL)
  68.                                     {
  69.                                         FirstBlock = Temp;
  70.                                     }
  71.                                  else
  72.                                     {
  73.                                         CheckHandleExistence((Handle)Lag);
  74.                                         (**Lag).Next = Temp;
  75.                                     }
  76.                                 ERROR((**Temp).NumBytes % BytesPerElement != 0,PRERR(ForceAbort,
  77.                                     "CSack::KillElement element array size inconsistency"));
  78.                                 ReleaseHandle((Handle)Scan);
  79.                                 if (((**Temp).NumElements == 0) && (Temp != FirstBlock))
  80.                                     {
  81.                                         (**Lag).Next = (**Temp).Next;
  82.                                         ReleaseHandle((Handle)Temp);
  83.                                     }
  84.                                 return True; /* return after deletion of one */
  85.                             }
  86.                     }
  87.                 Lag = Scan;
  88.                 Scan = (**Scan).Next;
  89.             }
  90.         return False;
  91.     }
  92.  
  93.  
  94. void                CSack::ResetScan(void)
  95.     {
  96.         ERROR(Initialized != True,PRERR(ForceAbort,
  97.             "CSack::ResetScan called on uninitialized object."));
  98.         NextHandleToAccess = FirstBlock;
  99.         NextIndexToAccess = -BytesPerElement; /* start out one before */
  100.         EXECUTE(Scannable = True;)
  101.     }
  102.  
  103.  
  104. MyBoolean        CSack::GetNext(void* PlaceToPut)
  105.     {
  106.         register short        Scan;
  107.  
  108.         ERROR(Initialized != True,PRERR(ForceAbort,
  109.             "CSack::GetNext called on uninitialized object."));
  110.         ERROR(!Scannable,PRERR(ForceAbort,
  111.             "CSack::GetNext called on unscannable object."));
  112.      RestartPoint:
  113.         if (NextHandleToAccess == NIL)
  114.             {
  115.                 return False;
  116.             }
  117.         CheckHandleExistence((Handle)NextHandleToAccess);
  118.         ERROR(NextIndexToAccess % BytesPerElement != 0,PRERR(ForceAbort,
  119.             "CSack::GetNext NextIndexToAccess inconsistency"));
  120.         ERROR((**NextHandleToAccess).NumBytes % BytesPerElement != 0,PRERR(ForceAbort,
  121.             "CSack::GetNext element array size inconsistency"));
  122.         NextIndexToAccess += BytesPerElement;
  123.         if (NextIndexToAccess >= (**NextHandleToAccess).NumBytes)
  124.             {
  125.                 NextHandleToAccess = (**NextHandleToAccess).Next;
  126.                 NextIndexToAccess = -BytesPerElement;
  127.                 goto RestartPoint;
  128.             }
  129.         HRNGCHK(NextHandleToAccess,&((**NextHandleToAccess).Data[NextIndexToAccess]),
  130.             BytesPerElement);
  131.         MemCpy(PlaceToPut,&((**NextHandleToAccess).Data[NextIndexToAccess]),BytesPerElement);
  132.         return True;
  133.     }
  134.  
  135.  
  136. ulong                CSack::NumElements(void)
  137.     {
  138.         register ulong                Accr;
  139.         register SackBlock**    Scan;
  140.  
  141.         ERROR(Initialized != True,PRERR(ForceAbort,
  142.             "CSack::NumElements called on uninitialized object."));
  143.         Accr = 0;
  144.         Scan = FirstBlock;
  145.         while (Scan != NIL)
  146.             {
  147.                 CheckHandleExistence((Handle)Scan);
  148.                 ERROR((**Scan).NumBytes % BytesPerElement != 0,PRERR(ForceAbort,
  149.                     "CSack::GetNext element array size inconsistency"));
  150.                 Accr += (**Scan).NumElements;
  151.                 Scan = (**Scan).Next;
  152.             }
  153.         return Accr;
  154.     }
  155.  
  156.  
  157. /* */                CSack::CSack()
  158.     {
  159.         SackBlock**            Shadow;
  160.  
  161.         SetTag(this,"CSack");
  162.         Shadow = (SackBlock**)AllocHandle(sizeof(SackBlock));
  163.         SetTag(Shadow,"CSack Block");
  164.         (**Shadow).Next = NIL;
  165.         (**Shadow).NumElements = 0;
  166.         (**Shadow).NumBytes = 0;
  167.         FirstBlock = Shadow;
  168.         EXECUTE(Scannable = False;)
  169.     }
  170.  
  171.  
  172. /* */                CSack::~CSack()
  173.     {
  174.         register SackBlock**    FirstImage;
  175.         register SackBlock**    Temp;
  176.  
  177.         ERROR(Initialized != True,PRERR(ForceAbort,
  178.             "CSack::~CSack called on uninitialized object."));
  179.         FirstImage = FirstBlock;
  180.         while (FirstImage != NIL)
  181.             {
  182.                 Temp = FirstImage;
  183.                 FirstImage = (**FirstImage).Next;
  184.                 ReleaseHandle((Handle)Temp);
  185.             }
  186.     }
  187.  
  188.  
  189. void                CSack::ISack(long TheSizeOfElement, long TheMaxElementsPerBlock)
  190.     {
  191.         ERROR(Initialized == True,PRERR(ForceAbort,
  192.             "CSack::ISack called on already initialized object."));
  193.         EXECUTE(Initialized = True);
  194.         BytesPerElement = TheSizeOfElement;
  195.         MaxBytesPerBlock = TheMaxElementsPerBlock * TheSizeOfElement;
  196.         ERROR((BytesPerElement<0)||(BytesPerElement>32767),PRERR(ForceAbort,
  197.             "CSack::ISack BytesPerElement initializer is out of range."));
  198.         ERROR((MaxBytesPerBlock<BytesPerElement)||(MaxBytesPerBlock>32767),PRERR(ForceAbort,
  199.             "CSack::ISack MaxBytesPerBlock initializer is out of range."));
  200.         EXECUTE(MaxBytesPerBlock = TheSizeOfElement * 4;) /* for error testing */
  201.     }
  202.  
  203.  
  204. MyBoolean        CSack::GetCurrent(void* PlaceToPut)
  205.     {
  206.         register short        Scan;
  207.  
  208.         ERROR(Initialized != True,PRERR(ForceAbort,
  209.             "CSack::GetCurrent called on uninitialized object."));
  210.         ERROR(!Scannable,PRERR(ForceAbort,
  211.             "CSack::GetCurrent called on unscannable object."));
  212.      RestartPoint:
  213.         if ((NextHandleToAccess == NIL) || (NextIndexToAccess < 0))
  214.             {
  215.                 return False;
  216.             }
  217.         HRNGCHK(NextHandleToAccess,&((**NextHandleToAccess).Data[NextIndexToAccess]),
  218.             BytesPerElement);
  219.         MemCpy(PlaceToPut,&((**NextHandleToAccess).Data[NextIndexToAccess]),BytesPerElement);
  220.         return True;
  221.     }
  222.  
  223.  
  224. MyBoolean        CSack::AdvanceToNext(void)
  225.     {
  226.         ERROR(Initialized != True,PRERR(ForceAbort,
  227.             "CSack::AdvanceToNext called on uninitialized object."));
  228.         ERROR(!Scannable,PRERR(ForceAbort,
  229.             "CSack::AdvanceToNext called on unscannable object."));
  230.      RestartPoint:
  231.         if (NextHandleToAccess == NIL)
  232.             {
  233.                 return False;
  234.             }
  235.         NextIndexToAccess += BytesPerElement;
  236.         if (NextIndexToAccess >= (**NextHandleToAccess).NumBytes)
  237.             {
  238.                 NextHandleToAccess = (**NextHandleToAccess).Next;
  239.                 NextIndexToAccess = 0;
  240.                 goto RestartPoint;
  241.             }
  242.         return True;
  243.     }
  244.  
  245.  
  246. /* insert after any that return negative or zero number, but before one that */
  247. /* returns a positive number (post-insertion sort) which allows us to use this */
  248. /* to implement a stable sort. */
  249. void                CSack::InsertSorted(void* Element, short (*Comparator)(void*,void*))
  250.     {
  251.         SackBlock**        SackScan;
  252.         SackBlock**        Lag;
  253.         SackBlock**        LookAhead;
  254.         long                    Index;
  255.         SackBlock**        Temp;
  256.         long                    Count;
  257.  
  258.         ERROR(Initialized != True,PRERR(ForceAbort,
  259.             "CSack::InsertSorted called on uninitialized object."));
  260.         EXECUTE(Scannable = False;)
  261.         /* First, find which block it should be inserted into. */
  262.      R